home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 June / MacFormat 25.iso / Shareware City / Developers / OutOfPhase1.1 Source / OutOfPhase Folder / TrackObject.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-19  |  68.2 KB  |  2,262 lines  |  [TEXT/KAHL]

  1. /* TrackObject.c */
  2. /*****************************************************************************/
  3. /*                                                                           */
  4. /*    Out Of Phase:  Digital Music Synthesis on General Purpose Computers    */
  5. /*    Copyright (C) 1994  Thomas R. Lawrence                                 */
  6. /*                                                                           */
  7. /*    This program is free software; you can redistribute it and/or modify   */
  8. /*    it under the terms of the GNU General Public License as published by   */
  9. /*    the Free Software Foundation; either version 2 of the License, or      */
  10. /*    (at your option) any later version.                                    */
  11. /*                                                                           */
  12. /*    This program is distributed in the hope that it will be useful,        */
  13. /*    but WITHOUT ANY WARRANTY; without even the implied warranty of         */
  14. /*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          */
  15. /*    GNU General Public License for more details.                           */
  16. /*                                                                           */
  17. /*    You should have received a copy of the GNU General Public License      */
  18. /*    along with this program; if not, write to the Free Software            */
  19. /*    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.              */
  20. /*                                                                           */
  21. /*    Thomas R. Lawrence can be reached at tomlaw@world.std.com.             */
  22. /*                                                                           */
  23. /*****************************************************************************/
  24.  
  25. #include "MiscInfo.h"
  26. #include "Audit.h"
  27. #include "Debug.h"
  28. #include "Definitions.h"
  29.  
  30. #include "TrackObject.h"
  31. #include "TrackWindow.h"
  32. #include "TrackList.h"
  33. #include "Memory.h"
  34. #include "DataMunging.h"
  35. #include "Array.h"
  36. #include "FrameObject.h"
  37. #include "Screen.h"
  38. #include "TrackView.h"
  39. #include "NoteObject.h"
  40. #include "Menus.h"
  41. #include "BufferedFileInput.h"
  42. #include "BufferedFileOutput.h"
  43. #include "BinaryCodedDecimal.h"
  44. #include "LoadSaveNoteVectors.h"
  45.  
  46.  
  47. struct TrackObjectRec
  48.     {
  49.         MyBoolean                                DataModified;
  50.  
  51.         char*                                        Name;
  52.  
  53.         /* defaults for per-note parameters */
  54.         double                                    DefaultEarlyLateAdjust;
  55.         double                                    DefaultReleasePoint1;
  56.         unsigned long                        DefaultReleasePoint1ModeFlag;
  57.         double                                    DefaultReleasePoint2;
  58.         unsigned long                        DefaultReleasePoint2ModeFlag;
  59.         double                                    DefaultOverallLoudness;
  60.         double                                    DefaultStereoPositioning;
  61.         double                                    DefaultSurroundPositioning;
  62.         double                                    DefaultAccent1;
  63.         double                                    DefaultAccent2;
  64.         double                                    DefaultAccent3;
  65.         double                                    DefaultAccent4;
  66.         double                                    DefaultPitchDisplacementDepthAdjust;
  67.         unsigned long                        DefaultPitchDisplacementDepthAdjustModeFlag;
  68.         double                                    DefaultPitchDisplacementRateAdjust;
  69.         double                                    DefaultPitchDisplacementStartPoint;
  70.         unsigned long                        DefaultPitchDisplacementStartPointModeFlag;
  71.         double                                    DefaultHurryUpFactor;
  72.         double                                    DefaultDetune;
  73.         unsigned long                        DefaultDetuneModeFlag;
  74.         double                                    DefaultDuration;
  75.         unsigned long                        DefaultDurationModeFlag;
  76.         char*                                        PostProcessingFormula;
  77.         MyBoolean                                PostProcessingEnable;
  78.  
  79.         MyBoolean                                IncludeThisTrackInFinalPlayback;
  80.  
  81.         char*                                        InstrumentName;
  82.         ArrayRec*                                FrameArray;
  83.         ArrayRec*                                DependentViews;
  84.         ArrayRec*                                BackgroundObjects;
  85.  
  86.         MenuItemType*                        TrackMenuItem;
  87.         TrackWindowRec*                    TrackWindow;
  88.  
  89.         struct CodeCenterRec*        CodeCenter;
  90.         struct MainWindowRec*        MainWindow;
  91.         TrackListRec*                        TrackList;
  92.  
  93.         short                                        SavedWindowXLoc;
  94.         short                                        SavedWindowYLoc;
  95.         short                                        SavedWindowWidth;
  96.         short                                        SavedWindowHeight;
  97.     };
  98.  
  99.  
  100. /* create a new empty track object */
  101. TrackObjectRec*                NewTrackObject(struct CodeCenterRec* CodeCenter,
  102.                                                 struct MainWindowRec* MainWindow, struct TrackListRec* TrackList)
  103.     {
  104.         TrackObjectRec*            TrackObj;
  105.         char*                                NullTerminated;
  106.  
  107.         TrackObj = (TrackObjectRec*)AllocPtrCanFail(sizeof(TrackObjectRec),"TrackObjectRec");
  108.         if (TrackObj == NIL)
  109.             {
  110.              FailurePoint1:
  111.                 return NIL;
  112.             }
  113.         TrackObj->Name = StringToBlockCopy("untitled");
  114.         if (TrackObj->Name == NIL)
  115.             {
  116.              FailurePoint2:
  117.                 ReleasePtr((char*)TrackObj);
  118.                 goto FailurePoint1;
  119.             }
  120.         TrackObj->InstrumentName = AllocPtrCanFail(0,"TrackObjInstrumentName");
  121.         if (TrackObj->InstrumentName == NIL)
  122.             {
  123.              FailurePoint3:
  124.                 ReleasePtr(TrackObj->Name);
  125.                 goto FailurePoint2;
  126.             }
  127.         TrackObj->FrameArray = NewArray();
  128.         if (TrackObj->FrameArray == NIL)
  129.             {
  130.              FailurePoint4:
  131.                 ReleasePtr(TrackObj->InstrumentName);
  132.                 goto FailurePoint3;
  133.             }
  134.         TrackObj->DependentViews = NewArray();
  135.         if (TrackObj->DependentViews == NIL)
  136.             {
  137.              FailurePoint5:
  138.                 DisposeArray(TrackObj->FrameArray);
  139.                 goto FailurePoint4;
  140.             }
  141.         TrackObj->BackgroundObjects = NewArray();
  142.         if (TrackObj->BackgroundObjects == NIL)
  143.             {
  144.              FailurePoint6:
  145.                 DisposeArray(TrackObj->DependentViews);
  146.                 goto FailurePoint5;
  147.             }
  148.         NullTerminated = BlockToStringCopy(TrackObj->Name);
  149.         if (NullTerminated == NIL)
  150.             {
  151.              FailurePoint7:
  152.                 DisposeArray(TrackObj->BackgroundObjects);
  153.                 goto FailurePoint6;
  154.             }
  155.         TrackObj->TrackMenuItem = MakeNewMenuItem(
  156.             TrackListGetTrackMenu(TrackList),NullTerminated,0);
  157.         ReleasePtr(NullTerminated);
  158.         if (TrackObj->TrackMenuItem == NIL)
  159.             {
  160.              FailurePoint8:
  161.                 goto FailurePoint7;
  162.             }
  163.         TrackObj->PostProcessingFormula = StringToBlockCopy("#channel postprocessing\x0a");
  164.         if (TrackObj->PostProcessingFormula == NIL)
  165.             {
  166.              FailurePoint9:
  167.                 KillMenuItem(TrackObj->TrackMenuItem);
  168.                 goto FailurePoint8;
  169.             }
  170.         SetTag(TrackObj->PostProcessingFormula,"PostProcessingFormula");
  171.  
  172.         TrackObj->DataModified = False;
  173.         TrackObj->TrackWindow = NIL;
  174.         TrackObj->CodeCenter = CodeCenter;
  175.         TrackObj->MainWindow = MainWindow;
  176.         TrackObj->TrackList = TrackList;
  177.         TrackObj->IncludeThisTrackInFinalPlayback = True;
  178.  
  179.         TrackObj->DefaultEarlyLateAdjust = 0;
  180.         TrackObj->DefaultReleasePoint1 = 0;
  181.         TrackObj->DefaultReleasePoint1ModeFlag = eRelease1FromStart;
  182.         TrackObj->DefaultReleasePoint2 = 0;
  183.         TrackObj->DefaultReleasePoint2ModeFlag = eRelease2FromStart;
  184.         TrackObj->DefaultOverallLoudness = 1;
  185.         TrackObj->DefaultStereoPositioning = 0;
  186.         TrackObj->DefaultSurroundPositioning = 0;
  187.         TrackObj->DefaultAccent1 = 0;
  188.         TrackObj->DefaultAccent2 = 0;
  189.         TrackObj->DefaultAccent3 = 0;
  190.         TrackObj->DefaultAccent4 = 0;
  191.         TrackObj->DefaultPitchDisplacementDepthAdjust = 1;
  192.         TrackObj->DefaultPitchDisplacementRateAdjust = 1;
  193.         TrackObj->DefaultPitchDisplacementStartPoint = 0;
  194.         TrackObj->DefaultPitchDisplacementStartPointModeFlag = ePitchDisplacementStartFromStart;
  195.         TrackObj->DefaultHurryUpFactor = 1;
  196.         TrackObj->DefaultDetune = 0;
  197.         TrackObj->DefaultDetuneModeFlag = eDetuningModeHalfSteps;
  198.         TrackObj->DefaultDuration = 0;
  199.         TrackObj->DefaultDurationModeFlag = eDurationAdjustAdditive;
  200.         TrackObj->PostProcessingEnable = False;
  201.  
  202.         TrackObj->SavedWindowXLoc = 0;
  203.         TrackObj->SavedWindowYLoc = 0;
  204.         TrackObj->SavedWindowWidth = 0;
  205.         TrackObj->SavedWindowHeight = 0;
  206.         return TrackObj;
  207.     }
  208.  
  209.  
  210. /* dispose of track object and all the crud it contains */
  211. void                                    DisposeTrackObject(TrackObjectRec* TrackObj)
  212.     {
  213.         long                                Limit;
  214.         long                                Scan;
  215.  
  216.         CheckPtrExistence(TrackObj);
  217.         if (TrackObj->TrackWindow != NIL)
  218.             {
  219.                 DisposeTrackWindow(TrackObj->TrackWindow);
  220.                 ERROR(TrackObj->TrackWindow != NIL,PRERR(ForceAbort,
  221.                     "DisposeTrackObject:  disposed track window, but window ptr isn't NIL"));
  222.             }
  223.         /* notify dependent views that this object is disappearing */
  224.         Limit = ArrayGetLength(TrackObj->DependentViews);
  225.         for (Scan = 0; Scan < Limit; Scan += 1)
  226.             {
  227.                 TrackViewRec*                ViewObject;
  228.  
  229.                 ViewObject = (TrackViewRec*)ArrayGetElement(TrackObj->DependentViews,Scan);
  230.                 TrackViewObjectTrackDying(ViewObject,TrackObj);
  231.             }
  232.         DisposeArray(TrackObj->DependentViews);
  233.         /* dispose list of background things. have the list dispose all ones */
  234.         /* depending on us. */
  235.         DisposeArray(TrackObj->BackgroundObjects);
  236.         TrackListDelinkBackgroundInstances(TrackObj->TrackList,TrackObj);
  237.         /* dispose notes */
  238.         Limit = ArrayGetLength(TrackObj->FrameArray);
  239.         for (Scan = 0; Scan < Limit; Scan += 1)
  240.             {
  241.                 FrameObjectRec*            Record;
  242.  
  243.                 Record = (FrameObjectRec*)ArrayGetElement(TrackObj->FrameArray,Scan);
  244.                 DisposeFrameAndContents(Record);
  245.             }
  246.         DisposeArray(TrackObj->FrameArray);
  247.         ReleasePtr(TrackObj->InstrumentName);
  248.         ReleasePtr(TrackObj->Name);
  249.         KillMenuItem(TrackObj->TrackMenuItem);
  250.         ReleasePtr(TrackObj->PostProcessingFormula);
  251.         ReleasePtr((char*)TrackObj);
  252.     }
  253.  
  254.  
  255. /* find out if the object has been changed */
  256. MyBoolean                            HasTrackObjectBeenModified(TrackObjectRec* TrackObj)
  257.     {
  258.         CheckPtrExistence(TrackObj);
  259.         /* unlike the other objects, the track object does NOT check the window */
  260.         /* to see if it has been changed because all data is always stored in */
  261.         /* the object itself for tracks */
  262.         return TrackObj->DataModified;
  263.     }
  264.  
  265.  
  266. /* get a copy of the object's name */
  267. char*                                    TrackObjectGetNameCopy(TrackObjectRec* TrackObj)
  268.     {
  269.         char*                                StringTemp;
  270.  
  271.         CheckPtrExistence(TrackObj);
  272.         StringTemp = CopyPtr(TrackObj->Name);
  273.         if (StringTemp != NIL)
  274.             {
  275.                 SetTag(StringTemp,"TrackObjectGetNameCopy");
  276.             }
  277.         return StringTemp;
  278.     }
  279.  
  280.  
  281. /* put a new name.  the object becomes the owner of the name block, so the */
  282. /* caller should not release it */
  283. void                                    TrackObjectPutName(TrackObjectRec* TrackObj, char* Name)
  284.     {
  285.         char*                                NullTerminated;
  286.  
  287.         CheckPtrExistence(TrackObj);
  288.         CheckPtrExistence(Name);
  289.         ReleasePtr(TrackObj->Name);
  290.         TrackObj->Name = Name;
  291.         SetTag(Name,"TrackObjectPutName name");
  292.         TrackObj->DataModified = True; /* no need to call TrackObjectAltered */
  293.         NullTerminated = BlockToStringCopy(Name);
  294.         if (NullTerminated != NIL)
  295.             {
  296.                 if (StrLen(NullTerminated) > 0)
  297.                     {
  298.                         /* it's bad to set menu item names to the empty string! */
  299.                         ChangeItemName(TrackObj->TrackMenuItem,NullTerminated);
  300.                     }
  301.                 ReleasePtr(NullTerminated);
  302.             }
  303.         TrackListTrackNameChanged(TrackObj->TrackList,TrackObj);
  304.     }
  305.  
  306.  
  307. /* get a copy of the name of the instrument that the track will be played with */
  308. char*                                    TrackObjectGetInstrName(TrackObjectRec* TrackObj)
  309.     {
  310.         char*                                StringTemp;
  311.  
  312.         CheckPtrExistence(TrackObj);
  313.         StringTemp = CopyPtr(TrackObj->InstrumentName);
  314.         if (StringTemp != NIL)
  315.             {
  316.                 SetTag(StringTemp,"TrackObjectGetInstrName name");
  317.             }
  318.         return StringTemp;
  319.     }
  320.  
  321.  
  322. /* change the name of the instrument that the track will be played with.  the */
  323. /* track object will become the owner of the block of memory. */
  324. void                                    TrackObjectPutNewInstrName(TrackObjectRec* TrackObj, char* Name)
  325.     {
  326.         CheckPtrExistence(TrackObj);
  327.         CheckPtrExistence(Name);
  328.         ReleasePtr(TrackObj->InstrumentName);
  329.         TrackObj->InstrumentName = Name;
  330.         SetTag(Name,"TrackObjectPutNewInstrName name");
  331.         TrackObj->DataModified = True; /* no need to call TrackObjectAltered */
  332.     }
  333.  
  334.  
  335. /* get a copy of the postprocessing formula */
  336. char*                                    TrackObjectGetPostProcessing(TrackObjectRec* TrackObj)
  337.     {
  338.         char*                                StringTemp;
  339.  
  340.         CheckPtrExistence(TrackObj);
  341.         StringTemp = CopyPtr(TrackObj->PostProcessingFormula);
  342.         if (StringTemp != NIL)
  343.             {
  344.                 SetTag(StringTemp,"PostProcessingFormula");
  345.             }
  346.         return StringTemp;
  347.     }
  348.  
  349.  
  350. /* change the postprocessing formula.  the object becomes owner of the memory block. */
  351. void                                    TrackObjectPutNewPostProcessing(TrackObjectRec* TrackObj,
  352.                                                 char* PostProcExpr)
  353.     {
  354.         CheckPtrExistence(TrackObj);
  355.         CheckPtrExistence(PostProcExpr);
  356.         ReleasePtr(TrackObj->PostProcessingFormula);
  357.         TrackObj->PostProcessingFormula = PostProcExpr;
  358.         SetTag(PostProcExpr,"PostProcessingFormula");
  359.         TrackObj->DataModified = True; /* no need to call TrackObjectAltered */
  360.     }
  361.  
  362.  
  363. /* get number of frames in track */
  364. long                                    TrackObjectGetNumFrames(TrackObjectRec* TrackObj)
  365.     {
  366.         CheckPtrExistence(TrackObj);
  367.         return ArrayGetLength(TrackObj->FrameArray);
  368.     }
  369.  
  370.  
  371. /* get the frame for a given track index */
  372. FrameObjectRec*                TrackObjectGetFrame(TrackObjectRec* TrackObj, long Index)
  373.     {
  374.         CheckPtrExistence(TrackObj);
  375.         ERROR((Index < 0) || (Index >= TrackObjectGetNumFrames(TrackObj)),PRERR(ForceAbort,
  376.             "TrackObjectGetFrame:  index out of range"));
  377.         return (FrameObjectRec*)ArrayGetElement(TrackObj->FrameArray,Index);
  378.     }
  379.  
  380.  
  381. /* delete a range of frames from the track. */
  382. void                                    TrackObjectDeleteFrameRun(TrackObjectRec* TrackObj,
  383.                                                 long Index, long Count)
  384.     {
  385.         long                                SourceFrameScan;
  386.         long                                SourceFrameLimit;
  387.  
  388.         CheckPtrExistence(TrackObj);
  389.         /* this thing is going to have to be redrawn */
  390.         TrackObjectAltered(TrackObj,Index);
  391.  
  392.         /* do the deletion */
  393.         for (SourceFrameScan = Index; SourceFrameScan < Index + Count; SourceFrameScan += 1)
  394.             {
  395.                 FrameObjectRec*            GallowsFrame;
  396.  
  397.                 GallowsFrame = (FrameObjectRec*)ArrayGetElement(TrackObj->FrameArray,Index);
  398.                 ArrayDeleteElement(TrackObj->FrameArray,Index);
  399.                 DisposeFrameAndContents(GallowsFrame);
  400.             }
  401.  
  402.         /* now we have to break any ties that are no longer valid (because their */
  403.         /* targets were just deleted) */
  404.         SourceFrameLimit = ArrayGetLength(TrackObj->FrameArray);
  405.         for (SourceFrameScan = 0; SourceFrameScan < SourceFrameLimit; SourceFrameScan += 1)
  406.             {
  407.                 FrameObjectRec*            SourceFrame;
  408.  
  409.                 SourceFrame = (FrameObjectRec*)ArrayGetElement(TrackObj->FrameArray,
  410.                     SourceFrameScan);
  411.                 /* it's either got some notes or one command */
  412.                 if (!IsThisACommandFrame(SourceFrame))
  413.                     {
  414.                         long                                SourceNoteLimit;
  415.                         long                                SourceNoteScan;
  416.  
  417.                         SourceNoteLimit = NumNotesInFrame(SourceFrame);
  418.                         for (SourceNoteScan = 0; SourceNoteScan < SourceNoteLimit;
  419.                             SourceNoteScan += 1)
  420.                             {
  421.                                 NoteObjectRec*            SourceNote;
  422.                                 NoteObjectRec*            TieTarget;
  423.  
  424.                                 SourceNote = GetNoteFromFrame(SourceFrame,SourceNoteScan);
  425.                                 TieTarget = GetNoteTieTarget(SourceNote);
  426.                                 if (TieTarget != NIL)
  427.                                     {
  428.                                         long                                TargetFrameLimit;
  429.                                         long                                TargetFrameScan;
  430.  
  431.                                         TargetFrameLimit = ArrayGetLength(TrackObj->FrameArray);
  432.                                         for (TargetFrameScan = 0; TargetFrameScan < TargetFrameLimit;
  433.                                             TargetFrameScan += 1)
  434.                                             {
  435.                                                 FrameObjectRec*            TargetFrame;
  436.  
  437.                                                 TargetFrame = (FrameObjectRec*)ArrayGetElement(
  438.                                                     TrackObj->FrameArray,TargetFrameScan);
  439.                                                 if (!IsThisACommandFrame(TargetFrame))
  440.                                                     {
  441.                                                         long                                TargetNoteLimit;
  442.                                                         long                                TargetNoteScan;
  443.  
  444.                                                         TargetNoteLimit = NumNotesInFrame(TargetFrame);
  445.                                                         for (TargetNoteScan = 0; TargetNoteScan < TargetNoteLimit;
  446.                                                             TargetNoteScan += 1)
  447.                                                             {
  448.                                                                 if (GetNoteFromFrame(TargetFrame,
  449.                                                                     TargetNoteScan) == TieTarget)
  450.                                                                     {
  451.                                                                         /* tie is valid, so no need to zap it */
  452.                                                                         goto TieValidPoint1;
  453.                                                                     }
  454.                                                             }
  455.                                                     }
  456.                                             } /* end inner frame list scan */
  457.                                         /* the target wasn't found, so we clobber it */
  458.                                         PutNoteTieTarget(SourceNote,NIL);
  459.                                      TieValidPoint1:
  460.                                         ;
  461.                                     }
  462.                             } /* end frame scan */
  463.                     }
  464.             } /* end frame list scan */
  465.     }
  466.  
  467.  
  468. /* get a list of frames and copy them out of the track */
  469. struct ArrayRec*            TrackObjectCopyFrameRun(TrackObjectRec* TrackObj,
  470.                                                 long Index, long Count)
  471.     {
  472.         ArrayRec*                        ReturnList;
  473.         long                                ReturnFrameScan;
  474.         long                                ReturnFrameLimit;
  475.  
  476.         CheckPtrExistence(TrackObj);
  477.  
  478.         /* create the list to hold all of the new things */
  479.         ReturnList = NewArrayReserveSpace(Count);
  480.         if (ReturnList == NIL)
  481.             {
  482.              FailurePoint1:
  483.                 return NIL;
  484.             }
  485.         ReturnFrameScan = Index;
  486.         while (ReturnFrameScan < Index + Count)
  487.             {
  488.                 FrameObjectRec*            OriginalFrame;
  489.                 FrameObjectRec*            DuplicateFrame;
  490.  
  491.                 OriginalFrame = (FrameObjectRec*)ArrayGetElement(TrackObj->FrameArray,
  492.                     ReturnFrameScan);
  493.                 DuplicateFrame = DeepDuplicateFrame(OriginalFrame);
  494.                 if (DuplicateFrame == NIL)
  495.                     {
  496.                      FailurePoint2:
  497.                         ReturnFrameLimit = ArrayGetLength(ReturnList);
  498.                         for (ReturnFrameScan = 0; ReturnFrameScan < ReturnFrameLimit;
  499.                             ReturnFrameScan += 1)
  500.                             {
  501.                                 DisposeFrameAndContents((FrameObjectRec*)ArrayGetElement(ReturnList,
  502.                                     ReturnFrameScan));
  503.                             }
  504.                         DisposeArray(ReturnList);
  505.                         goto FailurePoint1;
  506.                     }
  507.                 if (!ArrayAppendElement(ReturnList,DuplicateFrame))
  508.                     {
  509.                      FailurePoint2a:
  510.                         DisposeFrameAndContents(DuplicateFrame);
  511.                         goto FailurePoint2;
  512.                     }
  513.                 ReturnFrameScan += 1;
  514.             }
  515.  
  516.         /* now we have to patch up ties.  for each tie in the new array, find the */
  517.         /* note in the old array.  if it corresponds to a note we copied to the new */
  518.         /* array, then fix it up, otherwise set it to NIL. */
  519.         ReturnFrameLimit = ArrayGetLength(ReturnList);
  520.         for (ReturnFrameScan = 0; ReturnFrameScan < ReturnFrameLimit; ReturnFrameScan += 1)
  521.             {
  522.                 FrameObjectRec*            Frame;
  523.  
  524.                 Frame = (FrameObjectRec*)ArrayGetElement(ReturnList,ReturnFrameScan);
  525.                 /* it's either got some notes or one command */
  526.                 if (!IsThisACommandFrame(Frame))
  527.                     {
  528.                         long                                ReturnNoteLimit;
  529.                         long                                ReturnNoteScan;
  530.  
  531.                         ReturnNoteLimit = NumNotesInFrame(Frame);
  532.                         for (ReturnNoteScan = 0; ReturnNoteScan < ReturnNoteLimit;
  533.                             ReturnNoteScan += 1)
  534.                             {
  535.                                 NoteObjectRec*            Note;
  536.                                 NoteObjectRec*            OurNoteTieTarget;
  537.  
  538.                                 Note = GetNoteFromFrame(Frame,ReturnNoteScan);
  539.                                 OurNoteTieTarget = GetNoteTieTarget(Note);
  540.                                 if (OurNoteTieTarget != NIL)
  541.                                     {
  542.                                         long                                OriginalFrameLimit;
  543.                                         long                                OriginalFrameScan;
  544.  
  545.                                         OriginalFrameLimit = ArrayGetLength(TrackObj->FrameArray);
  546.                                         for (OriginalFrameScan = 0; OriginalFrameScan < OriginalFrameLimit;
  547.                                             OriginalFrameScan += 1)
  548.                                             {
  549.                                                 FrameObjectRec*            OrigFrame;
  550.  
  551.                                                 OrigFrame = (FrameObjectRec*)ArrayGetElement(
  552.                                                     TrackObj->FrameArray,OriginalFrameScan);
  553.                                                 if (!IsThisACommandFrame(OrigFrame))
  554.                                                     {
  555.                                                         long                                OriginalNoteLimit;
  556.                                                         long                                OriginalNoteScan;
  557.  
  558.                                                         OriginalNoteLimit = NumNotesInFrame(OrigFrame);
  559.                                                         for (OriginalNoteScan = 0; OriginalNoteScan
  560.                                                             < OriginalNoteLimit; OriginalNoteScan += 1)
  561.                                                             {
  562.                                                                 NoteObjectRec*            Possibility;
  563.  
  564.                                                                 Possibility = GetNoteFromFrame(OrigFrame,
  565.                                                                     OriginalNoteScan);
  566.                                                                 if (Possibility == OurNoteTieTarget)
  567.                                                                     {
  568.                                                                         /* found the tie target */
  569.                                                                         if ((OriginalFrameScan >= Index)
  570.                                                                             && (OriginalFrameScan < Index + Count))
  571.                                                                             {
  572.                                                                                 /* it's a valid tie, so fix it up */
  573.                                                                                 PutNoteTieTarget(Note,GetNoteFromFrame(
  574.                                                                                     (FrameObjectRec*)ArrayGetElement(ReturnList,
  575.                                                                                     OriginalFrameScan - Index),OriginalNoteScan));
  576.                                                                             }
  577.                                                                          else
  578.                                                                             {
  579.                                                                                 /* it isn't valid, so kill it */
  580.                                                                                 PutNoteTieTarget(Note,NIL);
  581.                                                                             }
  582.                                                                         goto TieValidPoint1;
  583.                                                                     }
  584.                                                             }
  585.                                                     }
  586.                                             } /* end inner frame list scan */
  587.                                         EXECUTE(PRERR(ForceAbort,
  588.                                             "TrackObjectCopyFrameRun:  tie target not found"));
  589.                                      TieValidPoint1:
  590.                                         ;
  591.                                     }
  592.                             } /* end frame scan */
  593.                     }
  594.             } /* end frame list scan */
  595.  
  596.         return ReturnList;
  597.     }
  598.  
  599.  
  600. /* find any notes that are referencing the specified note via a tie and nullify the tie. */
  601. void                                    TrackObjectNullifyTies(TrackObjectRec* TrackObj,
  602.                                                 struct NoteObjectRec* NoteThatIsDying)
  603.     {
  604.         long                                FrameScan;
  605.         long                                FrameLimit;
  606.  
  607.         CheckPtrExistence(TrackObj);
  608.         CheckPtrExistence(NoteThatIsDying);
  609.         FrameLimit = ArrayGetLength(TrackObj->FrameArray);
  610.         for (FrameScan = 0; FrameScan < FrameLimit; FrameScan += 1)
  611.             {
  612.                 FrameObjectRec*            Frame;
  613.                 long                                NoteScan;
  614.                 long                                NoteLimit;
  615.  
  616.                 Frame = (FrameObjectRec*)ArrayGetElement(TrackObj->FrameArray,FrameScan);
  617.                 CheckPtrExistence(Frame);
  618.                 NoteLimit = NumNotesInFrame(Frame);
  619.                 for (NoteScan = 0; NoteScan < NoteLimit; NoteScan += 1)
  620.                     {
  621.                         NoteObjectRec*            Note;
  622.  
  623.                         Note = GetNoteFromFrame(Frame,NoteScan);
  624.                         if (!IsItACommand(Note))
  625.                             {
  626.                                 if (GetNoteTieTarget(Note) == NoteThatIsDying)
  627.                                     {
  628.                                         PutNoteTieTarget(Note,NIL);
  629.                                     }
  630.                             }
  631.                     }
  632.             }
  633.         TrackObj->DataModified = True;
  634.     }
  635.  
  636.  
  637. /* insert a frame at the specified position */
  638. MyBoolean                            TrackObjectInsertFrame(TrackObjectRec* TrackObj, long Index,
  639.                                                 struct FrameObjectRec* NewFrame)
  640.     {
  641.         CheckPtrExistence(TrackObj);
  642.         CheckPtrExistence(NewFrame);
  643.         ERROR((Index < 0) || (Index > TrackObjectGetNumFrames(TrackObj)),PRERR(ForceAbort,
  644.             "TrackObjectInsertFrame:  index out of range"));
  645.         if (ArrayInsertElement(TrackObj->FrameArray,NewFrame,Index))
  646.             {
  647.                 TrackObjectAltered(TrackObj,Index);
  648.                 return True;
  649.             }
  650.          else
  651.             {
  652.                 return False;
  653.             }
  654.     }
  655.  
  656.  
  657. /* show the window for this object.  returns True if successful */
  658. MyBoolean                            TrackObjectOpenWindow(TrackObjectRec* TrackObj)
  659.     {
  660.         CheckPtrExistence(TrackObj);
  661.         if (TrackObj->TrackWindow != NIL)
  662.             {
  663.                 TrackWindowBringToTop(TrackObj->TrackWindow);
  664.             }
  665.          else
  666.             {
  667.                 TrackObj->TrackWindow = NewTrackWindow(TrackObj,TrackObj->MainWindow,
  668.                     TrackObj->TrackList,TrackObj->SavedWindowXLoc,TrackObj->SavedWindowYLoc,
  669.                     TrackObj->SavedWindowWidth,TrackObj->SavedWindowHeight);
  670.             }
  671.         return (TrackObj->TrackWindow != NIL);
  672.     }
  673.  
  674.  
  675. /* notify the object that it's window is closing.  the object should take no action */
  676. void                                    TrackObjectClosingWindowNotify(TrackObjectRec* TrackObj,
  677.                                                 short NewX, short NewY, short NewWidth, short NewHeight)
  678.     {
  679.         CheckPtrExistence(TrackObj);
  680.         ERROR(TrackObj->TrackWindow == NIL,PRERR(ForceAbort,
  681.             "TrackObjectClosingWindowNotify:  no window is open"));
  682.         TrackObj->TrackWindow = NIL;
  683.         TrackObj->SavedWindowXLoc = NewX;
  684.         TrackObj->SavedWindowYLoc = NewY;
  685.         TrackObj->SavedWindowWidth = NewWidth;
  686.         TrackObj->SavedWindowHeight = NewHeight;
  687.     }
  688.  
  689.  
  690. /* indicate that the track has been altered starting at a certain position */
  691. /* this sends a message to all track views that have been registered. */
  692. void                                    TrackObjectAltered(TrackObjectRec* TrackObj, long Index)
  693.     {
  694.         long                                Scan;
  695.         long                                Limit;
  696.  
  697.         CheckPtrExistence(TrackObj);
  698.         ERROR((Index < 0) || (Index > TrackObjectGetNumFrames(TrackObj)),PRERR(ForceAbort,
  699.             "TrackObjectAltered:  index out of range"));
  700.         TrackObj->DataModified = True;
  701.         Limit = ArrayGetLength(TrackObj->DependentViews);
  702.         for (Scan = 0; Scan < Limit; Scan += 1)
  703.             {
  704.                 TrackViewRec*                View;
  705.  
  706.                 View = (TrackViewRec*)ArrayGetElement(TrackObj->DependentViews,Scan);
  707.                 TrackViewTrackObjectModified(View,TrackObj,Index);
  708.             }
  709.     }
  710.  
  711.  
  712. /* add a track view object to the list of things that want to be notified when */
  713. /* data in this track is altered */
  714. MyBoolean                            TrackObjectAddDependentView(TrackObjectRec* TrackObj,
  715.                                                 struct TrackViewRec* TheView)
  716.     {
  717.         CheckPtrExistence(TrackObj);
  718.         CheckPtrExistence(TheView);
  719.         ERROR(ArrayFindElement(TrackObj->DependentViews,TheView) >= 0,PRERR(ForceAbort,
  720.             "TrackObjectAddDependentView:  view already on list"));
  721.         return ArrayAppendElement(TrackObj->DependentViews,TheView);
  722.     }
  723.  
  724.  
  725. /* remove a track view object that no longer wants to be notified upon changes */
  726. void                                    TrackObjectRemoveDependentView(TrackObjectRec* TrackObj,
  727.                                                 struct TrackViewRec* TheView)
  728.     {
  729.         CheckPtrExistence(TrackObj);
  730.         ERROR(ArrayFindElement(TrackObj->DependentViews,TheView) < 0,PRERR(ForceAbort,
  731.             "TrackObjectRemoveDependentView:  view isn't in list"));
  732.         ArrayDeleteElement(TrackObj->DependentViews,
  733.             ArrayFindElement(TrackObj->DependentViews,TheView));
  734.     }
  735.  
  736.  
  737. /* add a track view that wants to be seen in the background of this one. */
  738. /* this doesn't actually do too much, since we only keep the list, we don't */
  739. /* do any of the stuff required to actually show it in the background. */
  740. MyBoolean                            TrackObjectAddBackgroundObj(TrackObjectRec* TrackObj,
  741.                                                 TrackObjectRec* OtherTrackObj)
  742.     {
  743.         CheckPtrExistence(TrackObj);
  744.         CheckPtrExistence(OtherTrackObj);
  745.         ERROR(OtherTrackObj == TrackObj,PRERR(ForceAbort,
  746.             "TrackObjectAddBackgroundObj:  adding self to list"));
  747.         ERROR(ArrayFindElement(TrackObj->BackgroundObjects,OtherTrackObj) >= 0,
  748.             PRERR(ForceAbort,"TrackObjectAddBackgroundObj:  view already on list"));
  749.         return ArrayAppendElement(TrackObj->BackgroundObjects,OtherTrackObj);
  750.     }
  751.  
  752.  
  753. /* remove a track view that no longer wants to be seen in the background of this one */
  754. /* the list should call this on everyone when one is deleted so that there aren't */
  755. /* any dangling dependencies left around.  it is not an error to delete something */
  756. /* that isn't in the list */
  757. /* this doesn't actually do too much, since we only keep the list, we don't */
  758. /* do any of the stuff required to actually show it in the background. */
  759. void                                    TrackObjectRemoveBackgroundObj(TrackObjectRec* TrackObj,
  760.                                                 TrackObjectRec* OtherTrackObj)
  761.     {
  762.         long                                Position;
  763.  
  764.         CheckPtrExistence(TrackObj);
  765.         CheckPtrExistence(OtherTrackObj);
  766.         Position = ArrayFindElement(TrackObj->BackgroundObjects,OtherTrackObj);
  767.         if (Position >= 0)
  768.             {
  769.                 ArrayDeleteElement(TrackObj->BackgroundObjects,Position);
  770.             }
  771.     }
  772.  
  773.  
  774. /* get background object list.  (Actual thing). List of TrackObjectRec*'s */
  775. struct ArrayRec*            TrackObjectGetBackgroundList(TrackObjectRec* TrackObj)
  776.     {
  777.         CheckPtrExistence(TrackObj);
  778.         return TrackObj->BackgroundObjects;
  779.     }
  780.  
  781.  
  782. /* get the menu item associated with this track */
  783. struct MenuItemType*    TrackObjectGetMenuItem(TrackObjectRec* TrackObj)
  784.     {
  785.         CheckPtrExistence(TrackObj);
  786.         return TrackObj->TrackMenuItem;
  787.     }
  788.  
  789.  
  790. /* the document's name changed, so we need to update the window */
  791. void                                    TrackObjectGlobalNameChange(TrackObjectRec* TrackObj,
  792.                                                 char* NewFilename)
  793.     {
  794.         CheckPtrExistence(TrackObj);
  795.         if (TrackObj->TrackWindow != NIL)
  796.             {
  797.                 TrackWindowGlobalNameChange(TrackObj->TrackWindow,NewFilename);
  798.             }
  799.     }
  800.  
  801.  
  802. /* get the default early/late hit adjustment factor */
  803. double                                TrackObjectGetEarlyLateAdjust(TrackObjectRec* TrackObj)
  804.     {
  805.         CheckPtrExistence(TrackObj);
  806.         return TrackObj->DefaultEarlyLateAdjust;
  807.     }
  808.  
  809.  
  810. /* get the default first release point */
  811. double                                TrackObjectGetReleasePoint1(TrackObjectRec* TrackObj)
  812.     {
  813.         CheckPtrExistence(TrackObj);
  814.         return TrackObj->DefaultReleasePoint1;
  815.     }
  816.  
  817.  
  818. /* get the default first release point's from start or end flag (this is the same */
  819. /* as the mask used in each note) */
  820. unsigned long                    TrackObjectGetReleasePoint1StartEndFlag(TrackObjectRec* TrackObj)
  821.     {
  822.         CheckPtrExistence(TrackObj);
  823.         return TrackObj->DefaultReleasePoint1ModeFlag;
  824.     }
  825.  
  826.  
  827. /* get the default second release point */
  828. double                                TrackObjectGetReleasePoint2(TrackObjectRec* TrackObj)
  829.     {
  830.         CheckPtrExistence(TrackObj);
  831.         return TrackObj->DefaultReleasePoint2;
  832.     }
  833.  
  834.  
  835. /* get the default second release point's from start or end flag */
  836. unsigned long                    TrackObjectGetReleasePoint2StartEndFlag(TrackObjectRec* TrackObj)
  837.     {
  838.         CheckPtrExistence(TrackObj);
  839.         return TrackObj->DefaultReleasePoint2ModeFlag;
  840.     }
  841.  
  842.  
  843. /* get the default overall loudness adjustment factor */
  844. double                                TrackObjectGetOverallLoudness(TrackObjectRec* TrackObj)
  845.     {
  846.         CheckPtrExistence(TrackObj);
  847.         return TrackObj->DefaultOverallLoudness;
  848.     }
  849.  
  850.  
  851. /* get the default stereo positioning */
  852. double                                TrackObjectGetStereoPositioning(TrackObjectRec* TrackObj)
  853.     {
  854.         CheckPtrExistence(TrackObj);
  855.         return TrackObj->DefaultStereoPositioning;
  856.     }
  857.  
  858.  
  859. /* get the default surround positioning */
  860. double                                TrackObjectGetSurroundPositioning(TrackObjectRec* TrackObj)
  861.     {
  862.         CheckPtrExistence(TrackObj);
  863.         return TrackObj->DefaultSurroundPositioning;
  864.     }
  865.  
  866.  
  867. /* get the default first accent adjust */
  868. double                                TrackObjectGetAccent1(TrackObjectRec* TrackObj)
  869.     {
  870.         CheckPtrExistence(TrackObj);
  871.         return TrackObj->DefaultAccent1;
  872.     }
  873.  
  874.  
  875. /* get the default second accent adjust */
  876. double                                TrackObjectGetAccent2(TrackObjectRec* TrackObj)
  877.     {
  878.         CheckPtrExistence(TrackObj);
  879.         return TrackObj->DefaultAccent2;
  880.     }
  881.  
  882.  
  883. /* get the default third accent adjust */
  884. double                                TrackObjectGetAccent3(TrackObjectRec* TrackObj)
  885.     {
  886.         CheckPtrExistence(TrackObj);
  887.         return TrackObj->DefaultAccent3;
  888.     }
  889.  
  890.  
  891. /* get the default fourth accent adjust */
  892. double                                TrackObjectGetAccent4(TrackObjectRec* TrackObj)
  893.     {
  894.         CheckPtrExistence(TrackObj);
  895.         return TrackObj->DefaultAccent4;
  896.     }
  897.  
  898.  
  899. /* get the default pitch displacement depth adjust */
  900. double                                TrackObjectGetPitchDisplacementDepthAdjust(TrackObjectRec* TrackObj)
  901.     {
  902.         CheckPtrExistence(TrackObj);
  903.         return TrackObj->DefaultPitchDisplacementDepthAdjust;
  904.     }
  905.  
  906.  
  907. /* get the default pitch displacement rate adjust */
  908. double                                TrackObjectGetPitchDisplacementRateAdjust(TrackObjectRec* TrackObj)
  909.     {
  910.         CheckPtrExistence(TrackObj);
  911.         return TrackObj->DefaultPitchDisplacementRateAdjust;
  912.     }
  913.  
  914.  
  915. /* get the default pitch displacement start point */
  916. double                                TrackObjectGetPitchDisplacementStartPoint(TrackObjectRec* TrackObj)
  917.     {
  918.         CheckPtrExistence(TrackObj);
  919.         return TrackObj->DefaultPitchDisplacementStartPoint;
  920.     }
  921.  
  922.  
  923. /* get the default pitch displacement start point control flag */
  924. unsigned long                    TrackObjectGetPitchDisplacementFromStartOrEnd(
  925.                                                 TrackObjectRec* TrackObj)
  926.     {
  927.         CheckPtrExistence(TrackObj);
  928.         return TrackObj->DefaultPitchDisplacementStartPointModeFlag;
  929.     }
  930.  
  931.  
  932. /* get the default hurry-up factor */
  933. double                                TrackObjectGetHurryUp(TrackObjectRec* TrackObj)
  934.     {
  935.         CheckPtrExistence(TrackObj);
  936.         return TrackObj->DefaultHurryUpFactor;
  937.     }
  938.  
  939.  
  940. /* get the default detuning */
  941. double                                TrackObjectGetDetune(TrackObjectRec* TrackObj)
  942.     {
  943.         CheckPtrExistence(TrackObj);
  944.         return TrackObj->DefaultDetune;
  945.     }
  946.  
  947.  
  948. /* get the detuning control flag */
  949. unsigned long                    TrackObjectGetDetuneControlFlag(TrackObjectRec* TrackObj)
  950.     {
  951.         CheckPtrExistence(TrackObj);
  952.         return TrackObj->DefaultDetuneModeFlag;
  953.     }
  954.  
  955.  
  956. /* get the default duration adjustment */
  957. double                                TrackObjectGetDurationAdjust(TrackObjectRec* TrackObj)
  958.     {
  959.         CheckPtrExistence(TrackObj);
  960.         return TrackObj->DefaultDuration;
  961.     }
  962.  
  963.  
  964. /* get the default duration adjust mode flag */
  965. unsigned long                    TrackObjectGetDurationModeFlag(TrackObjectRec* TrackObj)
  966.     {
  967.         CheckPtrExistence(TrackObj);
  968.         return TrackObj->DefaultDurationModeFlag;
  969.     }
  970.  
  971.  
  972. /* change the default early/late hit adjustment factor */
  973. void                                    PutTrackObjectEarlyLateAdjust(TrackObjectRec* TrackObj,
  974.                                                 double NewEarlyLateAdjust)
  975.     {
  976.         CheckPtrExistence(TrackObj);
  977.         TrackObj->DefaultEarlyLateAdjust = NewEarlyLateAdjust;
  978.         TrackObj->DataModified = True;
  979.     }
  980.  
  981.  
  982. /* change the default first release point */
  983. void                                    PutTrackObjectReleasePoint1(TrackObjectRec* TrackObj,
  984.                                                 double NewReleasePoint1)
  985.     {
  986.         CheckPtrExistence(TrackObj);
  987.         TrackObj->DefaultReleasePoint1 = NewReleasePoint1;
  988.         TrackObj->DataModified = True;
  989.     }
  990.  
  991.  
  992. /* change the default first release point's from start or end flag */
  993. void                                    PutTrackObjectReleasePoint1StartEndFlag(TrackObjectRec* TrackObj,
  994.                                                 unsigned long NewReleasePoint1Flag)
  995.     {
  996.         CheckPtrExistence(TrackObj);
  997.         ERROR((NewReleasePoint1Flag != eRelease1FromStart)
  998.             && (NewReleasePoint1Flag != eRelease1FromEnd),PRERR(AllowResume,
  999.             "PutTrackObjectReleasePoint1StartEndFlag:  bad value"));
  1000.         TrackObj->DefaultReleasePoint1ModeFlag = NewReleasePoint1Flag;
  1001.         TrackObj->DataModified = True;
  1002.     }
  1003.  
  1004.  
  1005. /* change the default second release point */
  1006. void                                    PutTrackObjectReleasePoint2(TrackObjectRec* TrackObj,
  1007.                                                 double NewReleasePoint2)
  1008.     {
  1009.         CheckPtrExistence(TrackObj);
  1010.         TrackObj->DefaultReleasePoint2 = NewReleasePoint2;
  1011.         TrackObj->DataModified = True;
  1012.     }
  1013.  
  1014.  
  1015. /* change the default second release point's from start or end flag */
  1016. void                                    PutTrackObjectReleasePoint2StartEndFlag(TrackObjectRec* TrackObj,
  1017.                                                 unsigned long NewReleasePoint2Flag)
  1018.     {
  1019.         CheckPtrExistence(TrackObj);
  1020.         ERROR((NewReleasePoint2Flag != eRelease2FromStart)
  1021.             && (NewReleasePoint2Flag != eRelease2FromEnd),PRERR(AllowResume,
  1022.             "PutTrackObjectReleasePoint2StartEndFlag:  bad value"));
  1023.         TrackObj->DefaultReleasePoint2ModeFlag = NewReleasePoint2Flag;
  1024.         TrackObj->DataModified = True;
  1025.     }
  1026.  
  1027.  
  1028. /* change the default overall loudness adjustment factor */
  1029. void                                    PutTrackObjectOverallLoudness(TrackObjectRec* TrackObj,
  1030.                                                 double NewOverallLoudness)
  1031.     {
  1032.         CheckPtrExistence(TrackObj);
  1033.         TrackObj->DefaultOverallLoudness = NewOverallLoudness;
  1034.         TrackObj->DataModified = True;
  1035.     }
  1036.  
  1037.  
  1038. /* change the default stereo positioning value */
  1039. void                                    PutTrackObjectStereoPositioning(TrackObjectRec* TrackObj,
  1040.                                                 double NewStereoPositioning)
  1041.     {
  1042.         CheckPtrExistence(TrackObj);
  1043.         TrackObj->DefaultStereoPositioning = NewStereoPositioning;
  1044.         TrackObj->DataModified = True;
  1045.     }
  1046.  
  1047.  
  1048. /* change the default surround positioning value */
  1049. void                                    PutTrackObjectSurroundPositioning(TrackObjectRec* TrackObj,
  1050.                                                 double NewSurroundPositioning)
  1051.     {
  1052.         CheckPtrExistence(TrackObj);
  1053.         TrackObj->DefaultSurroundPositioning = NewSurroundPositioning;
  1054.         TrackObj->DataModified = True;
  1055.     }
  1056.  
  1057.  
  1058. /* change the default first accent adjust */
  1059. void                                    PutTrackObjectAccent1(TrackObjectRec* TrackObj,
  1060.                                                 double NewAccent1)
  1061.     {
  1062.         CheckPtrExistence(TrackObj);
  1063.         TrackObj->DefaultAccent1 = NewAccent1;
  1064.         TrackObj->DataModified = True;
  1065.     }
  1066.  
  1067.  
  1068. /* change the default second accent adjust */
  1069. void                                    PutTrackObjectAccent2(TrackObjectRec* TrackObj,
  1070.                                                 double NewAccent2)
  1071.     {
  1072.         CheckPtrExistence(TrackObj);
  1073.         TrackObj->DefaultAccent2 = NewAccent2;
  1074.         TrackObj->DataModified = True;
  1075.     }
  1076.  
  1077.  
  1078. /* change the default third accent adjust */
  1079. void                                    PutTrackObjectAccent3(TrackObjectRec* TrackObj,
  1080.                                                 double NewAccent3)
  1081.     {
  1082.         CheckPtrExistence(TrackObj);
  1083.         TrackObj->DefaultAccent3 = NewAccent3;
  1084.         TrackObj->DataModified = True;
  1085.     }
  1086.  
  1087.  
  1088. /* change the default fourth accent adjust */
  1089. void                                    PutTrackObjectAccent4(TrackObjectRec* TrackObj,
  1090.                                                 double NewAccent4)
  1091.     {
  1092.         CheckPtrExistence(TrackObj);
  1093.         TrackObj->DefaultAccent4 = NewAccent4;
  1094.         TrackObj->DataModified = True;
  1095.     }
  1096.  
  1097.  
  1098. /* change the default pitch displacement depth adjust */
  1099. void                                    PutTrackObjectPitchDisplacementDepthAdjust(TrackObjectRec* TrackObj,
  1100.                                                 double NewPitchDisplacementDepthAdjust)
  1101.     {
  1102.         CheckPtrExistence(TrackObj);
  1103.         TrackObj->DefaultPitchDisplacementDepthAdjust = NewPitchDisplacementDepthAdjust;
  1104.         TrackObj->DataModified = True;
  1105.     }
  1106.  
  1107.  
  1108. /* change the default pitch displacement rate adjust */
  1109. void                                    PutTrackObjectPitchDisplacementRateAdjust(TrackObjectRec* TrackObj,
  1110.                                                 double NewPitchDisplacementRate)
  1111.     {
  1112.         CheckPtrExistence(TrackObj);
  1113.         TrackObj->DefaultPitchDisplacementRateAdjust = NewPitchDisplacementRate;
  1114.         TrackObj->DataModified = True;
  1115.     }
  1116.  
  1117.  
  1118. /* change the default pitch displacement start point */
  1119. void                                    PutTrackObjectPitchDisplacementStartPoint(TrackObjectRec* TrackObj,
  1120.                                                 double NewPitchDisplacementStartPoint)
  1121.     {
  1122.         CheckPtrExistence(TrackObj);
  1123.         TrackObj->DefaultPitchDisplacementStartPoint = NewPitchDisplacementStartPoint;
  1124.         TrackObj->DataModified = True;
  1125.     }
  1126.  
  1127.  
  1128. /* change the default pitch displacement start point control flag */
  1129. void                                    PutTrackObjectPitchDisplacementFromStartOrEnd(TrackObjectRec*
  1130.                                                 TrackObj, unsigned long NewPitchDisplacementStartPointControl)
  1131.     {
  1132.         CheckPtrExistence(TrackObj);
  1133.         ERROR((NewPitchDisplacementStartPointControl != ePitchDisplacementStartFromStart)
  1134.             && (NewPitchDisplacementStartPointControl != ePitchDisplacementStartFromEnd),
  1135.             PRERR(AllowResume,"PutTrackObjectPitchDisplacementFromStartOrEnd:  bad value"));
  1136.         TrackObj->DefaultPitchDisplacementStartPointModeFlag
  1137.             = NewPitchDisplacementStartPointControl;
  1138.         TrackObj->DataModified = True;
  1139.     }
  1140.  
  1141.  
  1142. /* change the default hurry-up factor */
  1143. void                                    PutTrackObjectHurryUp(TrackObjectRec* TrackObj, double NewHurryUp)
  1144.     {
  1145.         CheckPtrExistence(TrackObj);
  1146.         TrackObj->DefaultHurryUpFactor = NewHurryUp;
  1147.         TrackObj->DataModified = True;
  1148.     }
  1149.  
  1150.  
  1151. /* change the default detuning */
  1152. void                                    PutTrackObjectDetune(TrackObjectRec* TrackObj, double NewDetune)
  1153.     {
  1154.         CheckPtrExistence(TrackObj);
  1155.         TrackObj->DefaultDetune = NewDetune;
  1156.         TrackObj->DataModified = True;
  1157.     }
  1158.  
  1159.  
  1160. /* change the detuning control flag */
  1161. void                                    PutTrackObjectDetuneControlFlag(TrackObjectRec* TrackObj,
  1162.                                                 unsigned long NewDetuneControlFlag)
  1163.     {
  1164.         CheckPtrExistence(TrackObj);
  1165.         ERROR((NewDetuneControlFlag != eDetuningModeHalfSteps)
  1166.             && (NewDetuneControlFlag != eDetuningModeHertz),PRERR(AllowResume,
  1167.             "PutTrackObjectDetuneControlFlag:  bad value"));
  1168.         TrackObj->DefaultDetuneModeFlag = NewDetuneControlFlag;
  1169.         TrackObj->DataModified = True;
  1170.     }
  1171.  
  1172.  
  1173. /* change the default duration adjustment */
  1174. void                                    PutTrackObjectDurationAdjust(TrackObjectRec* TrackObj,
  1175.                                                 double NewDurationAdjust)
  1176.     {
  1177.         CheckPtrExistence(TrackObj);
  1178.         TrackObj->DefaultDuration = NewDurationAdjust;
  1179.         TrackObj->DataModified = True;
  1180.     }
  1181.  
  1182.  
  1183. /* change the default duration adjust mode flag */
  1184. void                                    PutTrackObjectDurationModeFlag(TrackObjectRec* TrackObj,
  1185.                                                 unsigned long NewDurationModeFlag)
  1186.     {
  1187.         CheckPtrExistence(TrackObj);
  1188.         ERROR((NewDurationModeFlag != eDurationAdjustAdditive)
  1189.             && (NewDurationModeFlag != eDurationAdjustMultiplicative),PRERR(AllowResume,
  1190.             "PutTrackObjectDurationModeFlag:  bad value"));
  1191.         TrackObj->DefaultDurationModeFlag = NewDurationModeFlag;
  1192.         TrackObj->DataModified = True;
  1193.     }
  1194.  
  1195.  
  1196. /* find out if this track should be included when we play the score */
  1197. MyBoolean                            TrackObjectShouldItBePlayed(TrackObjectRec* TrackObj)
  1198.     {
  1199.         CheckPtrExistence(TrackObj);
  1200.         return TrackObj->IncludeThisTrackInFinalPlayback;
  1201.     }
  1202.  
  1203.  
  1204. /* chage status of whether track should be played */
  1205. void                                    ChangeTrackObjectShouldBePlayed(TrackObjectRec* TrackObj,
  1206.                                                 MyBoolean ShouldWePlayIt)
  1207.     {
  1208.         CheckPtrExistence(TrackObj);
  1209.         TrackObj->IncludeThisTrackInFinalPlayback = ShouldWePlayIt;
  1210.         /* don't set DataModified */
  1211.     }
  1212.  
  1213.  
  1214. /* Track Object Subblock Format: */
  1215. /*   1-byte format version number */
  1216. /*       should be 1 or 2 */
  1217. /*   2-byte little endian window X position (signed; from top-left corner of screen) */
  1218. /*   2-byte little endian window Y position */
  1219. /*   2-byte little endian window width */
  1220. /*   2-byte little endian window height */
  1221. /*   4-byte little endian track name length descriptor */
  1222. /*   n-byte track name string (line feed = 0x0a) */
  1223. /*   4-byte little endian large integer coded decimal default early/late adjust */
  1224. /*       large integer coded decimal is decimal * 1000000 with a */
  1225. /*       range of -1999.999999 to 1999.999999 */
  1226. /*   4-byte little endian large integer coded decimal default release point 1 */
  1227. /*   1-byte default release point 1 mode flag */
  1228. /*       0 = release from start */
  1229. /*       1 = release from end */
  1230. /*   4-byte little endian large integer coded decimal default release point 2 */
  1231. /*   1-byte default release point 2 mode flag */
  1232. /*       0 = release from start */
  1233. /*       1 = release from end */
  1234. /*   4-byte little endian large integer coded decimal default overall loudness */
  1235. /*   4-byte little endian large integer coded decimal default stereo positioning */
  1236. /*   4-byte little endian large integer coded decimal default surround positioning */
  1237. /*   4-byte little endian large integer coded decimal default accent 1 */
  1238. /*   4-byte little endian large integer coded decimal default accent 2 */
  1239. /*   4-byte little endian large integer coded decimal default accent 3 */
  1240. /*   4-byte little endian large integer coded decimal default accent 4 */
  1241. /*   4-byte little endian large integer coded decimal default pitch disp depth adjust */
  1242. /*   1-byte default pitch displacement depth adjust mode flag */
  1243. /*       0 = half steps */
  1244. /*       1 = hertz */
  1245. /*       this field has been eliminated in the version 2 file format! */
  1246. /*   4-byte little endian large integer coded decimal default pitch disp rate adjust */
  1247. /*   4-byte little endian large integer coded decimal default pitch disp start point */
  1248. /*   1-byte default pitch displacement start point mode flag */
  1249. /*       0 = pitch displacement point from start */
  1250. /*       1 = pitch displacement point from end */
  1251. /*   4-byte little endian large integer coded decimal default hurry-up factor */
  1252. /*   4-byte little endian large integer coded decimal default detuning */
  1253. /*   1-byte default detuning mode flag */
  1254. /*       0 = half steps */
  1255. /*       1 = hertz */
  1256. /*   4-byte little endian large integer coded decimal default duration */
  1257. /*   1-byte default duration mode flag */
  1258. /*       0 = duration adjust is multiplicative */
  1259. /*       1 = duration adjust is additive */
  1260. /*   1-byte flag for playback inclusion */
  1261. /*       0 = don't play track in final playback */
  1262. /*       1 = do play track in final playback */
  1263. /*   4-byte little endian instrument name string length descriptor */
  1264. /*   n-byte instrument name string (line feed = 0x0a) */
  1265. /*   1-byte flag for channel post processing enabling */
  1266. /*       0 = don't do channel postprocessing */
  1267. /*       1 = do channel postprocessing */
  1268. /*   4-byte little endian postprocessing expression length descriptor */
  1269. /*   n-bytes of postprocessing stuff (line feed = 0x0a) */
  1270. /*   n-bytes of data for note vector */
  1271.  
  1272.  
  1273. /* read track information from the file and create a new track object */
  1274. FileLoadingErrors            TrackObjectNewFromFile(TrackObjectRec** ObjectOut,
  1275.                                                 struct BufferedInputRec* Input, struct CodeCenterRec* CodeCenter,
  1276.                                                 struct MainWindowRec* MainWindow, struct TrackListRec* TrackList)
  1277.     {
  1278.         TrackObjectRec*            TrackObj;
  1279.         FileLoadingErrors        Error;
  1280.         unsigned char                UnsignedChar;
  1281.         signed short                SignedShort;
  1282.         signed long                    SignedLong;
  1283.         char*                                NullTerminated;
  1284.         short                                FormatVersionNumber;
  1285.  
  1286.         CheckPtrExistence(Input);
  1287.         CheckPtrExistence(CodeCenter);
  1288.         CheckPtrExistence(MainWindow);
  1289.         CheckPtrExistence(TrackList);
  1290.  
  1291.         TrackObj = (TrackObjectRec*)AllocPtrCanFail(sizeof(TrackObjectRec),"TrackObjectRec");
  1292.         if (TrackObj == NIL)
  1293.             {
  1294.                 Error = eFileLoadOutOfMemory;
  1295.              FailurePoint1:
  1296.                 return Error;
  1297.             }
  1298.  
  1299.         /*   1-byte format version number */
  1300.         /*       should be 1 or 2 */
  1301.         if (!ReadBufferedUnsignedChar(Input,&UnsignedChar))
  1302.             {
  1303.                 Error = eFileLoadDiskError;
  1304.              FailurePoint2:
  1305.                 ReleasePtr((char*)TrackObj);
  1306.                 goto FailurePoint1;
  1307.             }
  1308.         if ((UnsignedChar != 1) && (UnsignedChar != 2))
  1309.             {
  1310.                 Error = eFileLoadBadFormat;
  1311.              FailurePoint3:
  1312.                 goto FailurePoint2;
  1313.             }
  1314.         FormatVersionNumber = UnsignedChar;
  1315.  
  1316.         /*   2-byte little endian window X position (signed; from top-left corner of screen) */
  1317.         if (!ReadBufferedSignedShortLittleEndian(Input,&SignedShort))
  1318.             {
  1319.                 Error = eFileLoadDiskError;
  1320.              FailurePoint4:
  1321.                 goto FailurePoint3;
  1322.             }
  1323.         TrackObj->SavedWindowXLoc = SignedShort;
  1324.  
  1325.         /*   2-byte little endian window Y position */
  1326.         if (!ReadBufferedSignedShortLittleEndian(Input,&SignedShort))
  1327.             {
  1328.                 Error = eFileLoadDiskError;
  1329.              FailurePoint5:
  1330.                 goto FailurePoint4;
  1331.             }
  1332.         TrackObj->SavedWindowYLoc = SignedShort;
  1333.  
  1334.         /*   2-byte little endian window width */
  1335.         if (!ReadBufferedSignedShortLittleEndian(Input,&SignedShort))
  1336.             {
  1337.                 Error = eFileLoadDiskError;
  1338.              FailurePoint6:
  1339.                 goto FailurePoint5;
  1340.             }
  1341.         TrackObj->SavedWindowWidth = SignedShort;
  1342.  
  1343.         /*   2-byte little endian window height */
  1344.         if (!ReadBufferedSignedShortLittleEndian(Input,&SignedShort))
  1345.             {
  1346.                 Error = eFileLoadDiskError;
  1347.              FailurePoint7:
  1348.                 goto FailurePoint6;
  1349.             }
  1350.         TrackObj->SavedWindowHeight = SignedShort;
  1351.  
  1352.         /*   4-byte little endian track name length descriptor */
  1353.         if (!ReadBufferedSignedLongLittleEndian(Input,&SignedLong))
  1354.             {
  1355.                 Error = eFileLoadDiskError;
  1356.              FailurePoint8:
  1357.                 goto FailurePoint7;
  1358.             }
  1359.         if (SignedLong < 0)
  1360.             {
  1361.                 Error = eFileLoadBadFormat;
  1362.              FailurePoint9:
  1363.                 goto FailurePoint8;
  1364.             }
  1365.  
  1366.         /*   n-byte track name string (line feed = 0x0a) */
  1367.         TrackObj->Name = AllocPtrCanFail(SignedLong,"TrackObjectRec:  name");
  1368.         if (TrackObj->Name == NIL)
  1369.             {
  1370.                 Error = eFileLoadOutOfMemory;
  1371.              FailurePoint10:
  1372.                 goto FailurePoint9;
  1373.             }
  1374.         if (!ReadBufferedInput(Input,SignedLong,TrackObj->Name))
  1375.             {
  1376.                 Error = eFileLoadDiskError;
  1377.              FailurePoint11:
  1378.                 ReleasePtr(TrackObj->Name);
  1379.                 goto FailurePoint10;
  1380.             }
  1381.  
  1382.         /*   4-byte little endian large integer coded decimal default early/late adjust */
  1383.         /*       large integer coded decimal is decimal * 1000000 with a */
  1384.         /*       range of -1999.999999 to 1999.999999 */
  1385.         if (!ReadBufferedSignedLongLittleEndian(Input,&SignedLong))
  1386.             {
  1387.                 Error = eFileLoadDiskError;
  1388.              FailurePoint12:
  1389.                 goto FailurePoint11;
  1390.             }
  1391.         TrackObj->DefaultEarlyLateAdjust = LargeBCD2Double(SignedLong);
  1392.  
  1393.         /*   4-byte little endian large integer coded decimal default release point 1 */
  1394.         if (!ReadBufferedSignedLongLittleEndian(Input,&SignedLong))
  1395.             {
  1396.                 Error = eFileLoadDiskError;
  1397.              FailurePoint13:
  1398.                 goto FailurePoint12;
  1399.             }
  1400.         TrackObj->DefaultReleasePoint1 = LargeBCD2Double(SignedLong);
  1401.  
  1402.         /*   1-byte default release point 1 mode flag */
  1403.         /*       0 = release from start */
  1404.         /*       1 = release from end */
  1405.         if (!ReadBufferedUnsignedChar(Input,&UnsignedChar))
  1406.             {
  1407.                 Error = eFileLoadDiskError;
  1408.              FailurePoint14:
  1409.                 goto FailurePoint13;
  1410.             }
  1411.         if (UnsignedChar == 0)
  1412.             {
  1413.                 TrackObj->DefaultReleasePoint1ModeFlag = eRelease1FromStart;
  1414.             }
  1415.         else if (UnsignedChar == 1)
  1416.             {
  1417.                 TrackObj->DefaultReleasePoint1ModeFlag = eRelease1FromEnd;
  1418.             }
  1419.         else
  1420.             {
  1421.                 Error = eFileLoadBadFormat;
  1422.              FailurePoint15:
  1423.                 goto FailurePoint14;
  1424.             }
  1425.  
  1426.         /*   4-byte little endian large integer coded decimal default release point 2 */
  1427.         if (!ReadBufferedSignedLongLittleEndian(Input,&SignedLong))
  1428.             {
  1429.                 Error = eFileLoadDiskError;
  1430.              FailurePoint16:
  1431.                 goto FailurePoint15;
  1432.             }
  1433.         TrackObj->DefaultReleasePoint2 = LargeBCD2Double(SignedLong);
  1434.  
  1435.         /*   1-byte default release point 2 mode flag */
  1436.         /*       0 = release from start */
  1437.         /*       1 = release from end */
  1438.         if (!ReadBufferedUnsignedChar(Input,&UnsignedChar))
  1439.             {
  1440.                 Error = eFileLoadDiskError;
  1441.              FailurePoint17:
  1442.                 goto FailurePoint16;
  1443.             }
  1444.         if (UnsignedChar == 0)
  1445.             {
  1446.                 TrackObj->DefaultReleasePoint2ModeFlag = eRelease2FromStart;
  1447.             }
  1448.         else if (UnsignedChar == 1)
  1449.             {
  1450.                 TrackObj->DefaultReleasePoint2ModeFlag = eRelease2FromEnd;
  1451.             }
  1452.         else
  1453.             {
  1454.                 Error = eFileLoadBadFormat;
  1455.              FailurePoint18:
  1456.                 goto FailurePoint17;
  1457.             }
  1458.  
  1459.         /*   4-byte little endian large integer coded decimal default overall loudness */
  1460.         if (!ReadBufferedSignedLongLittleEndian(Input,&SignedLong))
  1461.             {
  1462.                 Error = eFileLoadDiskError;
  1463.              FailurePoint19:
  1464.                 goto FailurePoint18;
  1465.             }
  1466.         TrackObj->DefaultOverallLoudness = LargeBCD2Double(SignedLong);
  1467.  
  1468.         /*   4-byte little endian large integer coded decimal default stereo positioning */
  1469.         if (!ReadBufferedSignedLongLittleEndian(Input,&SignedLong))
  1470.             {
  1471.                 Error = eFileLoadDiskError;
  1472.              FailurePoint20:
  1473.                 goto FailurePoint19;
  1474.             }
  1475.         TrackObj->DefaultStereoPositioning = LargeBCD2Double(SignedLong);
  1476.  
  1477.         /*   4-byte little endian large integer coded decimal default surround positioning */
  1478.         if (!ReadBufferedSignedLongLittleEndian(Input,&SignedLong))
  1479.             {
  1480.                 Error = eFileLoadDiskError;
  1481.              FailurePoint20oops:
  1482.                 goto FailurePoint20;
  1483.             }
  1484.         TrackObj->DefaultSurroundPositioning = LargeBCD2Double(SignedLong);
  1485.  
  1486.         /*   4-byte little endian large integer coded decimal default accent 1 */
  1487.         if (!ReadBufferedSignedLongLittleEndian(Input,&SignedLong))
  1488.             {
  1489.                 Error = eFileLoadDiskError;
  1490.              FailurePoint21:
  1491.                 goto FailurePoint20oops;
  1492.             }
  1493.         TrackObj->DefaultAccent1 = LargeBCD2Double(SignedLong);
  1494.  
  1495.         /*   4-byte little endian large integer coded decimal default accent 2 */
  1496.         if (!ReadBufferedSignedLongLittleEndian(Input,&SignedLong))
  1497.             {
  1498.                 Error = eFileLoadDiskError;
  1499.              FailurePoint22:
  1500.                 goto FailurePoint21;
  1501.             }
  1502.         TrackObj->DefaultAccent2 = LargeBCD2Double(SignedLong);
  1503.  
  1504.         /*   4-byte little endian large integer coded decimal default accent 3 */
  1505.         if (!ReadBufferedSignedLongLittleEndian(Input,&SignedLong))
  1506.             {
  1507.                 Error = eFileLoadDiskError;
  1508.              FailurePoint23:
  1509.                 goto FailurePoint22;
  1510.             }
  1511.         TrackObj->DefaultAccent3 = LargeBCD2Double(SignedLong);
  1512.  
  1513.         /*   4-byte little endian large integer coded decimal default accent 4 */
  1514.         if (!ReadBufferedSignedLongLittleEndian(Input,&SignedLong))
  1515.             {
  1516.                 Error = eFileLoadDiskError;
  1517.              FailurePoint24:
  1518.                 goto FailurePoint23;
  1519.             }
  1520.         TrackObj->DefaultAccent4 = LargeBCD2Double(SignedLong);
  1521.  
  1522.         /*   4-byte little endian large integer coded decimal default pitch disp depth adjust */
  1523.         if (!ReadBufferedSignedLongLittleEndian(Input,&SignedLong))
  1524.             {
  1525.                 Error = eFileLoadDiskError;
  1526.              FailurePoint25:
  1527.                 goto FailurePoint24;
  1528.             }
  1529.         TrackObj->DefaultPitchDisplacementDepthAdjust = LargeBCD2Double(SignedLong);
  1530.  
  1531.         /*   1-byte default pitch displacement depth adjust mode flag */
  1532.         /*       0 = half steps */
  1533.         /*       1 = hertz */
  1534.         /*       this field has been eliminated in the version 2 file format! */
  1535.         if (FormatVersionNumber == 1)
  1536.             {
  1537.                 if (!ReadBufferedUnsignedChar(Input,&UnsignedChar))
  1538.                     {
  1539.                         Error = eFileLoadDiskError;
  1540.                      FailurePoint26:
  1541.                         goto FailurePoint25;
  1542.                     }
  1543.             }
  1544.  
  1545.         /*   4-byte little endian large integer coded decimal default pitch disp rate adjust */
  1546.         if (!ReadBufferedSignedLongLittleEndian(Input,&SignedLong))
  1547.             {
  1548.                 Error = eFileLoadDiskError;
  1549.              FailurePoint28:
  1550.                 goto FailurePoint26;
  1551.             }
  1552.         TrackObj->DefaultPitchDisplacementRateAdjust = LargeBCD2Double(SignedLong);
  1553.  
  1554.         /*   4-byte little endian large integer coded decimal default pitch disp start point */
  1555.         if (!ReadBufferedSignedLongLittleEndian(Input,&SignedLong))
  1556.             {
  1557.                 Error = eFileLoadDiskError;
  1558.              FailurePoint29:
  1559.                 goto FailurePoint28;
  1560.             }
  1561.         TrackObj->DefaultPitchDisplacementStartPoint = LargeBCD2Double(SignedLong);
  1562.  
  1563.         /*   1-byte default pitch displacement start point mode flag */
  1564.         /*       0 = pitch displacement point from start */
  1565.         /*       1 = pitch displacement point from end */
  1566.         if (!ReadBufferedUnsignedChar(Input,&UnsignedChar))
  1567.             {
  1568.                 Error = eFileLoadDiskError;
  1569.              FailurePoint30:
  1570.                 goto FailurePoint29;
  1571.             }
  1572.         if (UnsignedChar == 0)
  1573.             {
  1574.                 TrackObj->DefaultPitchDisplacementStartPointModeFlag
  1575.                     = ePitchDisplacementStartFromStart;
  1576.             }
  1577.         else if (UnsignedChar == 1)
  1578.             {
  1579.                 TrackObj->DefaultPitchDisplacementStartPointModeFlag
  1580.                     = ePitchDisplacementStartFromEnd;
  1581.             }
  1582.         else
  1583.             {
  1584.                 Error = eFileLoadBadFormat;
  1585.              FailurePoint31:
  1586.                 goto FailurePoint30;
  1587.             }
  1588.  
  1589.         /*   4-byte little endian large integer coded decimal default hurry-up factor */
  1590.         if (!ReadBufferedSignedLongLittleEndian(Input,&SignedLong))
  1591.             {
  1592.                 Error = eFileLoadDiskError;
  1593.              FailurePoint32:
  1594.                 goto FailurePoint31;
  1595.             }
  1596.         TrackObj->DefaultHurryUpFactor = LargeBCD2Double(SignedLong);
  1597.  
  1598.         /*   4-byte little endian large integer coded decimal default detuning */
  1599.         if (!ReadBufferedSignedLongLittleEndian(Input,&SignedLong))
  1600.             {
  1601.                 Error = eFileLoadDiskError;
  1602.              FailurePoint33:
  1603.                 goto FailurePoint32;
  1604.             }
  1605.         TrackObj->DefaultDetune = LargeBCD2Double(SignedLong);
  1606.  
  1607.         /*   1-byte default detuning mode flag */
  1608.         /*       0 = half steps */
  1609.         /*       1 = hertz */
  1610.         if (!ReadBufferedUnsignedChar(Input,&UnsignedChar))
  1611.             {
  1612.                 Error = eFileLoadDiskError;
  1613.              FailurePoint34:
  1614.                 goto FailurePoint33;
  1615.             }
  1616.         if (UnsignedChar == 0)
  1617.             {
  1618.                 TrackObj->DefaultDetuneModeFlag = eDetuningModeHalfSteps;
  1619.             }
  1620.         else if (UnsignedChar == 1)
  1621.             {
  1622.                 TrackObj->DefaultDetuneModeFlag = eDetuningModeHertz;
  1623.             }
  1624.         else
  1625.             {
  1626.                 Error = eFileLoadBadFormat;
  1627.              FailurePoint35:
  1628.                 goto FailurePoint34;
  1629.             }
  1630.  
  1631.         /*   4-byte little endian large integer coded decimal default duration */
  1632.         if (!ReadBufferedSignedLongLittleEndian(Input,&SignedLong))
  1633.             {
  1634.                 Error = eFileLoadDiskError;
  1635.              FailurePoint36:
  1636.                 goto FailurePoint35;
  1637.             }
  1638.         TrackObj->DefaultDuration = LargeBCD2Double(SignedLong);
  1639.  
  1640.         /*   1-byte default duration mode flag */
  1641.         /*       0 = duration adjust is multiplicative */
  1642.         /*       1 = duration adjust is additive */
  1643.         if (!ReadBufferedUnsignedChar(Input,&UnsignedChar))
  1644.             {
  1645.                 Error = eFileLoadDiskError;
  1646.              FailurePoint37:
  1647.                 goto FailurePoint36;
  1648.             }
  1649.         if (UnsignedChar == 0)
  1650.             {
  1651.                 TrackObj->DefaultDurationModeFlag = eDurationAdjustMultiplicative;
  1652.             }
  1653.         else if (UnsignedChar == 1)
  1654.             {
  1655.                 TrackObj->DefaultDurationModeFlag = eDurationAdjustAdditive;
  1656.             }
  1657.         else
  1658.             {
  1659.                 Error = eFileLoadBadFormat;
  1660.              FailurePoint38:
  1661.                 goto FailurePoint37;
  1662.             }
  1663.  
  1664.         /*   1-byte flag for playback inclusion */
  1665.         /*       0 = don't play track in final playback */
  1666.         /*       1 = do play track in final playback */
  1667.         if (!ReadBufferedUnsignedChar(Input,&UnsignedChar))
  1668.             {
  1669.                 Error = eFileLoadDiskError;
  1670.              FailurePoint39:
  1671.                 goto FailurePoint38;
  1672.             }
  1673.         if (UnsignedChar == 0)
  1674.             {
  1675.                 TrackObj->IncludeThisTrackInFinalPlayback = False;
  1676.             }
  1677.         else if (UnsignedChar == 1)
  1678.             {
  1679.                 TrackObj->IncludeThisTrackInFinalPlayback = True;
  1680.             }
  1681.         else
  1682.             {
  1683.                 Error = eFileLoadBadFormat;
  1684.              FailurePoint40:
  1685.                 goto FailurePoint39;
  1686.             }
  1687.  
  1688.         /*   4-byte little endian instrument name string length descriptor */
  1689.         if (!ReadBufferedSignedLongLittleEndian(Input,&SignedLong))
  1690.             {
  1691.                 Error = eFileLoadDiskError;
  1692.              FailurePoint41:
  1693.                 goto FailurePoint40;
  1694.             }
  1695.         if (SignedLong < 0)
  1696.             {
  1697.                 Error = eFileLoadBadFormat;
  1698.              FailurePoint42:
  1699.                 goto FailurePoint41;
  1700.             }
  1701.  
  1702.         /*   n-byte instrument name string (line feed = 0x0a) */
  1703.         TrackObj->InstrumentName = AllocPtrCanFail(SignedLong,"TrackObjectRec:  instr name");
  1704.         if (TrackObj->InstrumentName == NIL)
  1705.             {
  1706.                 Error = eFileLoadOutOfMemory;
  1707.              FailurePoint43:
  1708.                 goto FailurePoint42;
  1709.             }
  1710.         if (!ReadBufferedInput(Input,SignedLong,TrackObj->InstrumentName))
  1711.             {
  1712.                 Error = eFileLoadDiskError;
  1713.              FailurePoint44:
  1714.                 ReleasePtr(TrackObj->InstrumentName);
  1715.                 goto FailurePoint43;
  1716.             }
  1717.  
  1718.         /*   1-byte flag for channel post processing enabling */
  1719.         /*       0 = don't do channel postprocessing */
  1720.         /*       1 = do channel postprocessing */
  1721.         if (!ReadBufferedUnsignedChar(Input,&UnsignedChar))
  1722.             {
  1723.                 Error = eFileLoadDiskError;
  1724.              FailurePoint44a:
  1725.                 goto FailurePoint44;
  1726.             }
  1727.         if (UnsignedChar == 0)
  1728.             {
  1729.                 TrackObj->PostProcessingEnable = False;
  1730.             }
  1731.         else if (UnsignedChar == 1)
  1732.             {
  1733.                 TrackObj->PostProcessingEnable = True;
  1734.             }
  1735.         else
  1736.             {
  1737.                 Error = eFileLoadBadFormat;
  1738.              FailurePoint44b:
  1739.                 goto FailurePoint44a;
  1740.             }
  1741.  
  1742.         /*   4-byte little endian postprocessing expression length descriptor */
  1743.         if (!ReadBufferedSignedLongLittleEndian(Input,&SignedLong))
  1744.             {
  1745.                 Error = eFileLoadDiskError;
  1746.              FailurePoint45:
  1747.                 goto FailurePoint44b;
  1748.             }
  1749.         if (SignedLong < 0)
  1750.             {
  1751.                 Error = eFileLoadBadFormat;
  1752.              FailurePoint46:
  1753.                 goto FailurePoint45;
  1754.             }
  1755.  
  1756.         /*   n-bytes of postprocessing stuff (line feed = 0x0a) */
  1757.         TrackObj->PostProcessingFormula = AllocPtrCanFail(SignedLong,"PostProcessingFormula");
  1758.         if (TrackObj->PostProcessingFormula == NIL)
  1759.             {
  1760.                 Error = eFileLoadOutOfMemory;
  1761.              FailurePoint47:
  1762.                 goto FailurePoint46;
  1763.             }
  1764.         if (!ReadBufferedInput(Input,SignedLong,TrackObj->PostProcessingFormula))
  1765.             {
  1766.                 Error = eFileLoadDiskError;
  1767.              FailurePoint48:
  1768.                 ReleasePtr(TrackObj->PostProcessingFormula);
  1769.                 goto FailurePoint47;
  1770.             }
  1771.  
  1772.         /*   n-bytes of data for note array */
  1773.         EXECUTE(TrackObj->FrameArray = (ArrayRec*)0x81818181;)
  1774.         Error = ReadNoteVector(&(TrackObj->FrameArray),Input);
  1775.         if (Error != eFileLoadNoError)
  1776.             {
  1777.              FailurePoint49:
  1778.                 goto FailurePoint48;
  1779.             }
  1780.         CheckPtrExistence(TrackObj->FrameArray);
  1781.  
  1782.         /* fill in the other fields */
  1783.         TrackObj->DataModified = False;
  1784.         TrackObj->DependentViews = NewArray();
  1785.         if (TrackObj->DependentViews == NIL)
  1786.             {
  1787.                 long                        Scan;
  1788.                 long                        Limit;
  1789.  
  1790.                 Error = eFileLoadOutOfMemory;
  1791.              FailurePoint50:
  1792.                 Limit = ArrayGetLength(TrackObj->FrameArray);
  1793.                 for (Scan = 0; Scan < Limit; Scan += 1)
  1794.                     {
  1795.                         DisposeFrameAndContents((FrameObjectRec*)ArrayGetElement(
  1796.                             TrackObj->FrameArray,Scan));
  1797.                     }
  1798.                 goto FailurePoint49;
  1799.             }
  1800.         TrackObj->BackgroundObjects = NewArray();
  1801.         if (TrackObj->BackgroundObjects == NIL)
  1802.             {
  1803.                 Error = eFileLoadOutOfMemory;
  1804.              FailurePoint51:
  1805.                 DisposeArray(TrackObj->DependentViews);
  1806.                 goto FailurePoint50;
  1807.             }
  1808.         NullTerminated = BlockToStringCopy(TrackObj->Name);
  1809.         if (NullTerminated == NIL)
  1810.             {
  1811.                 Error = eFileLoadOutOfMemory;
  1812.              FailurePoint52:
  1813.                 goto FailurePoint51;
  1814.             }
  1815.         TrackObj->TrackMenuItem = MakeNewMenuItem(TrackListGetTrackMenu(TrackList),
  1816.             NullTerminated,0);
  1817.         if (TrackObj->TrackMenuItem == NIL)
  1818.             {
  1819.                 Error = eFileLoadOutOfMemory;
  1820.              FailurePoint52a:
  1821.                 ReleasePtr(NullTerminated);
  1822.                 goto FailurePoint52;
  1823.             }
  1824.         ReleasePtr(NullTerminated);
  1825.         TrackObj->TrackWindow = NIL;
  1826.         TrackObj->CodeCenter = CodeCenter;
  1827.         TrackObj->MainWindow = MainWindow;
  1828.         TrackObj->TrackList = TrackList;
  1829.  
  1830.         *ObjectOut = TrackObj;
  1831.         return eFileLoadNoError;
  1832.     }
  1833.  
  1834.  
  1835. /* write the track information to the file. */
  1836. FileLoadingErrors            TrackObjectWriteDataOut(TrackObjectRec* TrackObj,
  1837.                                                 struct BufferedOutputRec* Output)
  1838.     {
  1839.         char*                                StringTemp;
  1840.         FileLoadingErrors        Error;
  1841.  
  1842.         CheckPtrExistence(TrackObj);
  1843.         CheckPtrExistence(Output);
  1844.  
  1845.         /*   1-byte format version number */
  1846.         /*       should be 1 or 2 */
  1847.         if (!WriteBufferedUnsignedChar(Output,2))
  1848.             {
  1849.                 return eFileLoadDiskError;
  1850.             }
  1851.  
  1852.         /*   2-byte little endian window X position (signed; from top-left corner of screen) */
  1853.         /* if the window is open when the file is saved, then the most recent location */
  1854.         /* of the window will not be saved. */
  1855.         if (!WriteBufferedSignedShortLittleEndian(Output,TrackObj->SavedWindowXLoc))
  1856.             {
  1857.                 return eFileLoadDiskError;
  1858.             }
  1859.  
  1860.         /*   2-byte little endian window Y position */
  1861.         if (!WriteBufferedSignedShortLittleEndian(Output,TrackObj->SavedWindowYLoc))
  1862.             {
  1863.                 return eFileLoadDiskError;
  1864.             }
  1865.  
  1866.         /*   2-byte little endian window width */
  1867.         if (!WriteBufferedSignedShortLittleEndian(Output,TrackObj->SavedWindowWidth))
  1868.             {
  1869.                 return eFileLoadDiskError;
  1870.             }
  1871.  
  1872.         /*   2-byte little endian window height */
  1873.         if (!WriteBufferedSignedShortLittleEndian(Output,TrackObj->SavedWindowHeight))
  1874.             {
  1875.                 return eFileLoadDiskError;
  1876.             }
  1877.  
  1878.         /*   4-byte little endian track name length descriptor */
  1879.         StringTemp = TrackObjectGetNameCopy(TrackObj);
  1880.         if (StringTemp == NIL)
  1881.             {
  1882.                 return eFileLoadOutOfMemory;
  1883.             }
  1884.         if (!WriteBufferedSignedLongLittleEndian(Output,PtrSize(StringTemp)))
  1885.             {
  1886.                 ReleasePtr(StringTemp);
  1887.                 return eFileLoadDiskError;
  1888.             }
  1889.  
  1890.         /*   n-byte track name string (line feed = 0x0a) */
  1891.         if (!WriteBufferedOutput(Output,PtrSize(StringTemp),StringTemp))
  1892.             {
  1893.                 ReleasePtr(StringTemp);
  1894.                 return eFileLoadDiskError;
  1895.             }
  1896.         ReleasePtr(StringTemp);
  1897.  
  1898.         /*   4-byte little endian large integer coded decimal default early/late adjust */
  1899.         /*       large integer coded decimal is decimal * 1000000 with a */
  1900.         /*       range of -1999.999999 to 1999.999999 */
  1901.         if (!WriteBufferedSignedLongLittleEndian(Output,
  1902.             Double2LargeBCD(TrackObjectGetEarlyLateAdjust(TrackObj))))
  1903.             {
  1904.                 return eFileLoadDiskError;
  1905.             }
  1906.  
  1907.         /*   4-byte little endian large integer coded decimal default release point 1 */
  1908.         if (!WriteBufferedSignedLongLittleEndian(Output,
  1909.             Double2LargeBCD(TrackObjectGetReleasePoint1(TrackObj))))
  1910.             {
  1911.                 return eFileLoadDiskError;
  1912.             }
  1913.  
  1914.         /*   1-byte default release point 1 mode flag */
  1915.         /*       0 = release from start */
  1916.         /*       1 = release from end */
  1917.         switch (TrackObjectGetReleasePoint1StartEndFlag(TrackObj))
  1918.             {
  1919.                 default:
  1920.                     EXECUTE(PRERR(ForceAbort,"TrackObjectWriteDataOut:  bad value "
  1921.                         "from TrackObjectGetReleasePoint1StartEndFlag"));
  1922.                     break;
  1923.                 case eRelease1FromStart:
  1924.                     if (!WriteBufferedUnsignedChar(Output,0))
  1925.                         {
  1926.                             return eFileLoadDiskError;
  1927.                         }
  1928.                     break;
  1929.                 case eRelease1FromEnd:
  1930.                     if (!WriteBufferedUnsignedChar(Output,1))
  1931.                         {
  1932.                             return eFileLoadDiskError;
  1933.                         }
  1934.                     break;
  1935.             }
  1936.  
  1937.         /*   4-byte little endian large integer coded decimal default release point 2 */
  1938.         if (!WriteBufferedSignedLongLittleEndian(Output,
  1939.             Double2LargeBCD(TrackObjectGetReleasePoint2(TrackObj))))
  1940.             {
  1941.                 return eFileLoadDiskError;
  1942.             }
  1943.  
  1944.         /*   1-byte default release point 2 mode flag */
  1945.         /*       0 = release from start */
  1946.         /*       1 = release from end */
  1947.         switch (TrackObjectGetReleasePoint2StartEndFlag(TrackObj))
  1948.             {
  1949.                 default:
  1950.                     EXECUTE(PRERR(ForceAbort,"TrackObjectWriteDataOut:  bad value "
  1951.                         "from TrackObjectGetReleasePoint2StartEndFlag"));
  1952.                     break;
  1953.                 case eRelease2FromStart:
  1954.                     if (!WriteBufferedUnsignedChar(Output,0))
  1955.                         {
  1956.                             return eFileLoadDiskError;
  1957.                         }
  1958.                     break;
  1959.                 case eRelease2FromEnd:
  1960.                     if (!WriteBufferedUnsignedChar(Output,1))
  1961.                         {
  1962.                             return eFileLoadDiskError;
  1963.                         }
  1964.                     break;
  1965.             }
  1966.  
  1967.         /*   4-byte little endian large integer coded decimal default overall loudness */
  1968.         if (!WriteBufferedSignedLongLittleEndian(Output,
  1969.             Double2LargeBCD(TrackObjectGetOverallLoudness(TrackObj))))
  1970.             {
  1971.                 return eFileLoadDiskError;
  1972.             }
  1973.  
  1974.         /*   4-byte little endian large integer coded decimal default stereo positioning */
  1975.         if (!WriteBufferedSignedLongLittleEndian(Output,
  1976.             Double2LargeBCD(TrackObjectGetStereoPositioning(TrackObj))))
  1977.             {
  1978.                 return eFileLoadDiskError;
  1979.             }
  1980.  
  1981.         /*   4-byte little endian large integer coded decimal default surround positioning */
  1982.         if (!WriteBufferedSignedLongLittleEndian(Output,
  1983.             Double2LargeBCD(TrackObjectGetSurroundPositioning(TrackObj))))
  1984.             {
  1985.                 return eFileLoadDiskError;
  1986.             }
  1987.  
  1988.         /*   4-byte little endian large integer coded decimal default accent 1 */
  1989.         if (!WriteBufferedSignedLongLittleEndian(Output,
  1990.             Double2LargeBCD(TrackObjectGetAccent1(TrackObj))))
  1991.             {
  1992.                 return eFileLoadDiskError;
  1993.             }
  1994.  
  1995.         /*   4-byte little endian large integer coded decimal default accent 2 */
  1996.         if (!WriteBufferedSignedLongLittleEndian(Output,
  1997.             Double2LargeBCD(TrackObjectGetAccent2(TrackObj))))
  1998.             {
  1999.                 return eFileLoadDiskError;
  2000.             }
  2001.  
  2002.         /*   4-byte little endian large integer coded decimal default accent 3 */
  2003.         if (!WriteBufferedSignedLongLittleEndian(Output,
  2004.             Double2LargeBCD(TrackObjectGetAccent3(TrackObj))))
  2005.             {
  2006.                 return eFileLoadDiskError;
  2007.             }
  2008.  
  2009.         /*   4-byte little endian large integer coded decimal default accent 4 */
  2010.         if (!WriteBufferedSignedLongLittleEndian(Output,
  2011.             Double2LargeBCD(TrackObjectGetAccent4(TrackObj))))
  2012.             {
  2013.                 return eFileLoadDiskError;
  2014.             }
  2015.  
  2016.         /*   4-byte little endian large integer coded decimal default pitch disp depth adjust */
  2017.         if (!WriteBufferedSignedLongLittleEndian(Output,
  2018.             Double2LargeBCD(TrackObjectGetPitchDisplacementDepthAdjust(TrackObj))))
  2019.             {
  2020.                 return eFileLoadDiskError;
  2021.             }
  2022.  
  2023.         /*   4-byte little endian large integer coded decimal default pitch disp rate adjust */
  2024.         if (!WriteBufferedSignedLongLittleEndian(Output,
  2025.             Double2LargeBCD(TrackObjectGetPitchDisplacementRateAdjust(TrackObj))))
  2026.             {
  2027.                 return eFileLoadDiskError;
  2028.             }
  2029.  
  2030.         /*   4-byte little endian large integer coded decimal default pitch disp start point */
  2031.         if (!WriteBufferedSignedLongLittleEndian(Output,
  2032.             Double2LargeBCD(TrackObjectGetPitchDisplacementStartPoint(TrackObj))))
  2033.             {
  2034.                 return eFileLoadDiskError;
  2035.             }
  2036.  
  2037.         /*   1-byte default pitch displacement start point mode flag */
  2038.         /*       0 = pitch displacement point from start */
  2039.         /*       1 = pitch displacement point from end */
  2040.         switch (TrackObjectGetPitchDisplacementFromStartOrEnd(TrackObj))
  2041.             {
  2042.                 default:
  2043.                     EXECUTE(PRERR(ForceAbort,"TrackObjectWriteDataOut:  bad value "
  2044.                         "from TrackObjectGetPitchDisplacementFromStartOrEnd"));
  2045.                     break;
  2046.                 case ePitchDisplacementStartFromStart:
  2047.                     if (!WriteBufferedUnsignedChar(Output,0))
  2048.                         {
  2049.                             return eFileLoadDiskError;
  2050.                         }
  2051.                     break;
  2052.                 case ePitchDisplacementStartFromEnd:
  2053.                     if (!WriteBufferedUnsignedChar(Output,1))
  2054.                         {
  2055.                             return eFileLoadDiskError;
  2056.                         }
  2057.                     break;
  2058.             }
  2059.  
  2060.         /*   4-byte little endian large integer coded decimal default hurry-up factor */
  2061.         if (!WriteBufferedSignedLongLittleEndian(Output,
  2062.             Double2LargeBCD(TrackObjectGetHurryUp(TrackObj))))
  2063.             {
  2064.                 return eFileLoadDiskError;
  2065.             }
  2066.  
  2067.         /*   4-byte little endian large integer coded decimal default detuning */
  2068.         if (!WriteBufferedSignedLongLittleEndian(Output,
  2069.             Double2LargeBCD(TrackObjectGetDetune(TrackObj))))
  2070.             {
  2071.                 return eFileLoadDiskError;
  2072.             }
  2073.  
  2074.         /*   1-byte default detuning mode flag */
  2075.         /*       0 = half steps */
  2076.         /*       1 = hertz */
  2077.         switch (TrackObjectGetDetuneControlFlag(TrackObj))
  2078.             {
  2079.                 default:
  2080.                     EXECUTE(PRERR(ForceAbort,"TrackObjectWriteDataOut:  bad value "
  2081.                         "from TrackObjectGetDetuneControlFlag"));
  2082.                     break;
  2083.                 case eDetuningModeHalfSteps:
  2084.                     if (!WriteBufferedUnsignedChar(Output,0))
  2085.                         {
  2086.                             return eFileLoadDiskError;
  2087.                         }
  2088.                     break;
  2089.                 case eDetuningModeHertz:
  2090.                     if (!WriteBufferedUnsignedChar(Output,1))
  2091.                         {
  2092.                             return eFileLoadDiskError;
  2093.                         }
  2094.                     break;
  2095.             }
  2096.  
  2097.         /*   4-byte little endian large integer coded decimal default duration */
  2098.         if (!WriteBufferedSignedLongLittleEndian(Output,
  2099.             Double2LargeBCD(TrackObjectGetDurationAdjust(TrackObj))))
  2100.             {
  2101.                 return eFileLoadDiskError;
  2102.             }
  2103.  
  2104.         /*   1-byte default duration mode flag */
  2105.         /*       0 = duration adjust is multiplicative */
  2106.         /*       1 = duration adjust is additive */
  2107.         switch (TrackObjectGetDurationModeFlag(TrackObj))
  2108.             {
  2109.                 default:
  2110.                     EXECUTE(PRERR(ForceAbort,"TrackObjectWriteDataOut:  bad value "
  2111.                         "from TrackObjectGetDurationModeFlag"));
  2112.                     break;
  2113.                 case eDurationAdjustMultiplicative:
  2114.                     if (!WriteBufferedUnsignedChar(Output,0))
  2115.                         {
  2116.                             return eFileLoadDiskError;
  2117.                         }
  2118.                     break;
  2119.                 case eDurationAdjustAdditive:
  2120.                     if (!WriteBufferedUnsignedChar(Output,1))
  2121.                         {
  2122.                             return eFileLoadDiskError;
  2123.                         }
  2124.                     break;
  2125.             }
  2126.  
  2127.         /*   1-byte flag for playback inclusion */
  2128.         /*       0 = don't play track in final playback */
  2129.         /*       1 = do play track in final playback */
  2130.         if (TrackObjectShouldItBePlayed(TrackObj))
  2131.             {
  2132.                 if (!WriteBufferedUnsignedChar(Output,1))
  2133.                     {
  2134.                         return eFileLoadDiskError;
  2135.                     }
  2136.             }
  2137.          else
  2138.             {
  2139.                 if (!WriteBufferedUnsignedChar(Output,0))
  2140.                     {
  2141.                         return eFileLoadDiskError;
  2142.                     }
  2143.             }
  2144.  
  2145.         /*   4-byte little endian instrument name string length descriptor */
  2146.         StringTemp = TrackObjectGetInstrName(TrackObj);
  2147.         if (StringTemp == NIL)
  2148.             {
  2149.                 return eFileLoadOutOfMemory;
  2150.             }
  2151.         if (!WriteBufferedSignedLongLittleEndian(Output,PtrSize(StringTemp)))
  2152.             {
  2153.                 ReleasePtr(StringTemp);
  2154.                 return eFileLoadDiskError;
  2155.             }
  2156.  
  2157.         /*   n-byte instrument name string (line feed = 0x0a) */
  2158.         if (!WriteBufferedOutput(Output,PtrSize(StringTemp),StringTemp))
  2159.             {
  2160.                 ReleasePtr(StringTemp);
  2161.                 return eFileLoadDiskError;
  2162.             }
  2163.         ReleasePtr(StringTemp);
  2164.  
  2165.         /*   1-byte flag for channel post processing enabling */
  2166.         /*       0 = don't do channel postprocessing */
  2167.         /*       1 = do channel postprocessing */
  2168.         if (TrackObj->PostProcessingEnable)
  2169.             {
  2170.                 if (!WriteBufferedUnsignedChar(Output,1))
  2171.                     {
  2172.                         return eFileLoadDiskError;
  2173.                     }
  2174.             }
  2175.          else
  2176.             {
  2177.                 if (!WriteBufferedUnsignedChar(Output,0))
  2178.                     {
  2179.                         return eFileLoadDiskError;
  2180.                     }
  2181.             }
  2182.  
  2183.         /*   4-byte little endian postprocessing expression length descriptor */
  2184.         StringTemp = TrackObjectGetPostProcessing(TrackObj);
  2185.         if (StringTemp == NIL)
  2186.             {
  2187.                 return eFileLoadOutOfMemory;
  2188.             }
  2189.         if (!WriteBufferedSignedLongLittleEndian(Output,PtrSize(StringTemp)))
  2190.             {
  2191.                 ReleasePtr(StringTemp);
  2192.                 return eFileLoadDiskError;
  2193.             }
  2194.  
  2195.         /*   n-bytes of postprocessing stuff (line feed = 0x0a) */
  2196.         if (!WriteBufferedOutput(Output,PtrSize(StringTemp),StringTemp))
  2197.             {
  2198.                 ReleasePtr(StringTemp);
  2199.                 return eFileLoadDiskError;
  2200.             }
  2201.         ReleasePtr(StringTemp);
  2202.  
  2203.         /*   n-bytes of data for note array */
  2204.         Error = WriteNoteVector(TrackObj->FrameArray,Output);
  2205.         if (Error != eFileLoadNoError)
  2206.             {
  2207.                 return Error;
  2208.             }
  2209.  
  2210.         return eFileLoadNoError;
  2211.     }
  2212.  
  2213.  
  2214. /* mark track object as saved */
  2215. void                                    TrackObjectMarkAsSaved(TrackObjectRec* TrackObj)
  2216.     {
  2217.         CheckPtrExistence(TrackObj);
  2218.         /* there is no state data in the window */
  2219.         TrackObj->DataModified = False;
  2220.     }
  2221.  
  2222.  
  2223. /* make the track object write out the note array to the file */
  2224. MyBoolean                            TrackObjectWriteNotesOutToFile(TrackObjectRec* TrackObj,
  2225.                                                 struct BufferedOutputRec* Output)
  2226.     {
  2227.         CheckPtrExistence(TrackObj);
  2228.         CheckPtrExistence(Output);
  2229.         return (eFileLoadNoError == WriteNoteVector(TrackObj->FrameArray,Output));
  2230.     }
  2231.  
  2232.  
  2233. /* load notes from the file & replace track's notes with them */
  2234. MyBoolean                            TrackObjectRecoverNotesFromFile(TrackObjectRec* TrackObj,
  2235.                                                 struct BufferedInputRec* Input)
  2236.     {
  2237.         ArrayRec*                        NewNoteVector EXECUTE(= (ArrayRec*)0x81818181);
  2238.         long                                Limit;
  2239.         long                                Scan;
  2240.  
  2241.         CheckPtrExistence(TrackObj);
  2242.         CheckPtrExistence(Input);
  2243.         /* get the new vector */
  2244.         if (eFileLoadNoError != ReadNoteVector(&NewNoteVector,Input))
  2245.             {
  2246.                 return False;
  2247.             }
  2248.         CheckPtrExistence(NewNoteVector);
  2249.         /* delete the old one */
  2250.         Limit = ArrayGetLength(TrackObj->FrameArray);
  2251.         for (Scan = 0; Scan < Limit; Scan += 1)
  2252.             {
  2253.                 DisposeFrameAndContents((FrameObjectRec*)ArrayGetElement(
  2254.                     TrackObj->FrameArray,Scan));
  2255.             }
  2256.         DisposeArray(TrackObj->FrameArray);
  2257.         /* install the new one */
  2258.         TrackObj->FrameArray = NewNoteVector;
  2259.         TrackObjectAltered(TrackObj,0);
  2260.         return True;
  2261.     }
  2262.